#include "LogicSystem.h"

#include "Global.h"
#include "HttpConnection.h"
#include "MysqlMgr.h"
#include "RedisMgr.h"
#include "VarifyGrpcClient.h"

LogicSystem::~LogicSystem() {}

bool LogicSystem::HandleGet(std::string path,
                            std::shared_ptr<HttpConnection> con) {
  // 从get请求中寻找指定路由，未找到指定路由直接返回
  if (_get_handlers.find(path) == _get_handlers.end()) {
    return false;
  }

  // 找到指定get路由，从get路由取出回调执行本次get请求
  _get_handlers[path](con);
  return true;
}

bool LogicSystem::HandlePost(std::string path,
                             std::shared_ptr<HttpConnection> con) {
  // 从get请求中寻找指定路由，未找到指定路由直接返回
  if (_post_handlers.find(path) == _post_handlers.end()) {
    return false;
  }

  // 找到指定get路由，从get路由取出回调执行本次get请求
  _post_handlers[path](con);
  return true;
}

void LogicSystem::RegGet(std::string url, HttpHandler handler) {
  _get_handlers.insert({url, handler});
}

void LogicSystem::RegPost(std::string url, HttpHandler handler) {
  _post_handlers.insert({url, handler});
}

LogicSystem::LogicSystem() {
  RegGet("/get_test", [](std::shared_ptr<HttpConnection> connection) {
    beast::ostream(connection->_response.body()) << "receive get_test req";
    int i = 0;
    for (auto& elem : connection->_get_params) {
      i++;
      beast::ostream(connection->_response.body())
          << "param" << i << " key is " << elem.first;
      beast::ostream(connection->_response.body())
          << ", "
          << " value is " << elem.second << std::endl;
    }
  });

  RegPost("/get_varifycode", [](std::shared_ptr<HttpConnection> connection) {
    auto body_str =
        boost::beast::buffers_to_string(connection->_request.body().data());
    std::cout << "receive body is " << body_str << std::endl;

    connection->_response.set(http::field::content_type, "application/json");
    Json::Value root;
    Json::Reader reader;
    Json::Value src_root;
    bool parse_success = reader.parse(body_str, src_root);
    if (!parse_success) {
      std::cout << "Failed to parse JSON data!" << std::endl;
      root["error"] = ErrorCodes::Error_Json;
      std::string jsonstr = root.toStyledString();
      beast::ostream(connection->_response.body()) << jsonstr;
      return true;
    }

    auto email = src_root["email"].asString();
    GetVarifyResponse rsp =
        VarifyGrpcClient::GetInstance()->GetVarifyCode(email);

    std::cout << "status:" << rsp.error_code() << " email:" << rsp.email()
              << " code:" << rsp.verify_code()
              << " message:" << rsp.error_message();

    std::cout << "email is " << email << std::endl;
    root["error_code"] = rsp.error_code();
    root["email"] = src_root["email"];
    root["error_message"] = rsp.error_message();
    root["varify_code"] = rsp.verify_code();
    std::string jsonstr = root.toStyledString();
    beast::ostream(connection->_response.body()) << jsonstr;
    return true;
  });

  RegPost("/user_register", [](std::shared_ptr<HttpConnection> connection) {
    auto body_str =
        boost::beast::buffers_to_string(connection->_request.body().data());
    std::cout << "receive body is " << body_str << std::endl;

    connection->_response.set(http::field::content_type, "application/json");
    Json::Value root;
    Json::Reader reader;
    Json::Value src_root;

    bool parse_success = reader.parse(body_str, src_root);
    if (!parse_success) {
      std::cout << "Failed to parse JSON data!" << std::endl;
      root["Error"] = ErrorCodes::Error_Json;
      std::string jsonstr = root.toStyledString();
      beast::ostream(connection->_response.body()) << jsonstr;
      return true;
    }

    auto name = src_root["User"].asString();
    auto pwd = src_root["Pwd"].asString();
    auto email = src_root["Email"].asString();
    auto confirm = src_root["Confirm"].asString();
    auto varify_code = src_root["Varify_Code"].asString();

    // 校验两次密码是否一致
    if (pwd != confirm) {
      std::cout << "两次密码不一致!" << std::endl;
      root["Error"] = ErrorCodes::PasswdErr;
      std::string jsonstr = root.toStyledString();
      beast::ostream(connection->_response.body()) << jsonstr;
      return true;
    }

    string code_value;
    // 查找redis中email对应的验证码是否合理
    bool b_get_varify =
        RedisMgr::GetInstance()->Get(code_prefix + email, code_value);

    if (!b_get_varify) {
      std::cout << "验证码不存在!" << std::endl;
      root["Error"] = ErrorCodes::VarifyCodeErr;
      std::string jsonstr = root.toStyledString();
      beast::ostream(connection->_response.body()) << jsonstr;
      return true;
    }

    if (varify_code != code_value) {
      std::cout << "验证码错误!" << std::endl;
      root["Error"] = ErrorCodes::VarifyCodeErr;
      std::string jsonstr = root.toStyledString();
      beast::ostream(connection->_response.body()) << jsonstr;
      return true;
    }

    // 查找数据库判断用户是否存在
    int uid = MysqlMgr::GetInstance()->RegUser(name, email, pwd);
    if (uid == 0 || uid == -1) {
      std::cout << " 邮箱或者账户存在，注册用户失败!" << std::endl;
      root["Error"] = ErrorCodes::UserExist;
      std::string jsonstr = root.toStyledString();
      beast::ostream(connection->_response.body()) << jsonstr;
      return true;
    }

    root["Error"] = 0;
    root["Uid"] = uid;
    root["Email"] = email;
    root["User"] = name;
    root["Passwd"] = pwd;
    root["Confirm"] = confirm;
    root["Varify_Code"] = src_root["Varify_Code"].asString();
    std::string jsonstr = root.toStyledString();
    beast::ostream(connection->_response.body()) << jsonstr;
    return true;
  });

  RegPost("/user_reset", [](std::shared_ptr<HttpConnection> connection) {
    auto body_str =
        boost::beast::buffers_to_string(connection->_request.body().data());
    std::cout << "receive body is " << body_str << std::endl;

    connection->_response.set(http::field::content_type, "application/json");
    Json::Value root;      // 用于构建错误响应的 JSON
    Json::Reader reader;   // json解析器
    Json::Value src_root;  // 用于存储解析后的源数据

    // 解析request请求体中的JSON,并存储在src_root中
    bool parse_success = reader.parse(body_str, src_root);
    if (!parse_success) {
      std::cout << "Failed to parse JSON data!" << std::endl;
      root["Error"] = ErrorCodes::Error_Json;
      root["Msg"] = "Failed to parse JSON data!";
      std::string jsonstr = root.toStyledString();  // 生成格式化 JSON 字符串
      beast::ostream(connection->_response.body()) << jsonstr;  // 写入响应体
      return true;
    }

    auto email = src_root["Email"].asString();
    auto user = src_root["User"].asString();
    auto pwd = src_root["Pwd"].asString();
    auto varify_code = src_root["Varify_Code"].asString();

    // 查找redis，看验证码是否有效
    string code_value;
    bool b_get_varify =
        RedisMgr::GetInstance()->Get(code_prefix + email, code_value);
    if (!b_get_varify) {
      std::cout << "get varify code expired!" << std::endl;
      root["Error"] = ErrorCodes::VarifyExpired;
      root["Msg"] = "验证码已过期，请重新获取验证码!";
      std::string jsonstr = root.toStyledString();
      beast::ostream(connection->_response.body()) << jsonstr;
      return true;
    }

    // 如果验证码存在，则判断验证码是否正确
    if (varify_code != code_value) {
      std::cout << "varify code error!" << std::endl;
      root["Error"] = ErrorCodes::VarifyCodeErr;
      root["Msg"] = "验证码错误!";
      std::string jsonstr = root.toStyledString();
      beast::ostream(connection->_response.body()) << jsonstr;
      return true;
    }

    // 查询数据库判断用户名和邮箱是否匹配
    bool b_check_res = MysqlMgr::GetInstance()->checkEmail(user, email);
    if (!b_check_res) {
      std::cout << "user or email not match!" << std::endl;
      root["Error"] = ErrorCodes::EmailNotMatch;
      root["Msg"] = "用户名或邮箱不匹配!";  
      auto jsonStr = root.toStyledString();
      beast::ostream(connection->_response.body()) << jsonStr;
      return true;
    }

    // 修改用户密码
    bool b_update_pwd = MysqlMgr::GetInstance()->updatePwd(user, pwd);
    if (!b_update_pwd) {
      std::cout << "update user password failed!" << std::endl;
      root["Error"] = ErrorCodes::PasswdUpFailed;
      root["Msg"] = "修改密码失败!";
      std::string jsonstr = root.toStyledString();
      beast::ostream(connection->_response.body()) << jsonstr;
      return true;
    }

    // 重置成功，返回成功响应
    root["Error"] = 0;
    root["Msg"] = "密码修改成功!";
    std::string jsonstr = root.toStyledString();
    beast::ostream(connection->_response.body()) << jsonstr;
    return true;
  });

}
